﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

namespace ElevateThis
{
    public static class ProcessLauncher
    {
        /// <summary>
        /// Launches this process with elevation, providing the new process with enough information
        /// to run the original batch file
        /// </summary>
        public static ExitCode RelaunchElevated(Options options)
        {
            ExitCode retCode = ExitCode.Success;

            FileInfo batchFile = new FileInfo(options.BatchFile);

            // Use the directory we're launched from as the working directory.  Fallback to the batch file's directory
            string workDirectory = Directory.GetCurrentDirectory();
            if (String.IsNullOrEmpty(workDirectory)) workDirectory = batchFile.DirectoryName;

            // Need full path to this EXE
            string elevationExe = Assembly.GetExecutingAssembly().Location;

            // Build up args for the relaunch
            string args = String.Format("{0} {1}", Constants.ARG_LAUNCHSTATE, LaunchStates.RelaunchedElevated);
            args += String.Format(" {0} {1}", Constants.ARG_BATCHFILE, options.BatchFile);
            args += String.Format(" {0} {1}", Constants.ARG_BATCHARGS, options.ArgumentList);
            args += String.Format(" {0} {1}", Constants.ARG_WORKINGDIR, workDirectory);

            // Relaunch ourselves elevated
            Process newProc = new Process();
            newProc.StartInfo.FileName = elevationExe;
            newProc.StartInfo.Arguments = args;
            newProc.StartInfo.Verb = "RunAs";
            newProc.Start();

            Diagnostics.ShowLaunchedProcess(newProc);

            return retCode;
        }


        /// <summary>
        /// Launch the batch file in a new process using the current command window
        /// </summary>
        public static ExitCode LaunchBatchFile(Options options)
        {
            // We should be elevated now
            if (!UACHelper.IsProcessElevated) throw new ApplicationException("Relaunched, but this process is still not elevated");

            // cmd.exe /c ""batch file.bat" args"
            Process newProc = new Process();
            newProc.StartInfo.FileName = "cmd.exe";
            newProc.StartInfo.Arguments = String.Format("/c \"\"{0}\" {1}\"", options.BatchFile, options.ArgumentList);
            newProc.StartInfo.WorkingDirectory = options.WorkingDir;

            // "UseShellExecute = false" means it doesn't launch a new command window
            newProc.StartInfo.UseShellExecute = false;

            newProc.Start();

            Diagnostics.ShowLaunchedProcess(newProc);

            newProc.WaitForExit();

            return ExitCode.Success;
        }
    }
}
